#include "flash.h"
/*
    FLASH 1k字节/页
*/

/*
    按字编程
*/

u32 flash_programword(u32 address, u32 *p_source, u32 len)
{
    u32 i = 0;
    FLASH_Unlock();
    for (i = 0; i < len; i++)
    {
        if (FLASH_ProgramWord(address, *(u32 *)(p_source + i)) == FLASH_COMPLETE)
        {
            if (*(u32 *)address != *(u32 *)(p_source + i))
            {
                return FALSE;
            }
            address += 4;
        }
        else
        {
            FLASH_Lock();
            return FALSE;
        }
    }
    FLASH_Lock();
    return TRUE;
}

/*
    按半字编程
*/
void flash_programhalfword(u32 address, u16 data)
{
    FLASH_Unlock();
    if (FLASH_ProgramHalfWord(address, data) != FLASH_COMPLETE)
        printf("write data error!\r\n");
    FLASH_Lock();
}

/*
    按字读
*/
u32 flash_readword(u32 address, u32 *p_source, u16 cnt)
{
    u16 idx;
    for (idx = 0; idx < cnt; idx++)
    {
        *(p_source + idx) = *(((u32 *)address) + idx);
    }
    return TRUE;
}

/*
    按字节读取
*/
u8 flash_readbyte(u32 address, u8 *p_source, u16 cnt)
{
    u16 idx;
    for (idx = 0; idx < cnt; idx++)
    {
        *(p_source + idx) = *(((u8 *)address) + idx);
    }
    return TRUE;
}
/*
    全擦除
*/
void flash_eraseallpages(void)
{
    FLASH_Unlock();                              // 解锁
    if (FLASH_EraseAllPages() != FLASH_COMPLETE) // 全擦除
        printf("erase all pages error!\r\n");
    FLASH_Lock();
}

/*
    页擦除
*/

u16 flash_erasepage(u32 pageAddress)
{
    u16 idx;
    u16 wk_ret = TRUE;
    FLASH_Unlock();
    if (FLASH_ErasePage(pageAddress) == FLASH_COMPLETE)
    {
        for (idx = 0; idx < PAGE_SIZE; idx += 4)
        {
            if (*((u32 *)(pageAddress + idx)) != 0xFFFFFFFF)
            {
                wk_ret = FALSE;
            }
        }
    }
    else
    {
        wk_ret = FALSE;
    }
    FLASH_Lock();
    return wk_ret;
}

flash_t *flashCreate(void)
{
    static flash_t flash;
    flash.PflashProgramWord=flash_programword;
    flash.PflashReadWord=flash_readword;
    flash.PflashReadByte=flash_readbyte;
    flash.PflashEraseAllPages=flash_eraseallpages;
    flash.PflashErasePage=flash_erasepage;
    return &flash;
}
